/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bd.master;

import java.net.*;
import javax.xml.namespace.QName;
import bd.util.*;
import java.util.*;
import java.io.*;
import javax.xml.ws.Endpoint;
import javax.jws.*;

/**
 *
 * @author niyaz
 */
@WebService
public class Master {

    public String file = "data";
    ArrayList<Record> records = new ArrayList<Record>();
    Parameters parameters = new Parameters();
     bd.artefacts.Balancer balancer;
    String myAddress = "";


    public void setParameters(Parameters p) {
        this.parameters = p;
    }

    ;

    public void run() {

        System.out.println("1 if you whould work like alon base, 2 if you would work like part of a bigger base");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        try {
            str = br.readLine();
        } catch (Exception e) {
        }
        ;

        if (str.equalsIgnoreCase("1")) {

            File f = new File(file);
            if (f.exists()) {
                load(file);
            }
            ;

            System.out.println("Insert your inet address, 'http://localhost:7070/MasterService/service' whould be default");

            try {
                str = br.readLine();
            } catch (Exception e) {
            }
            ;

            if (str.equalsIgnoreCase("")) {
                str = "http://localhost:7070/MasterService/service";
            }

            myAddress = str;
            System.out.println("Adress whould be " + str);


           publish(str);



            control();

            System.exit(0);

        } else {


           
            
            
            System.out.println("Insert your inet address, 'http://localhost:6060/MasterService/service' whould be default");

            try {
                str = br.readLine();
            } catch (Exception e) {
            }
            ;

            if (str.equalsIgnoreCase("")) {
                str = "http://localhost:6060/MasterService/service";
            }

            myAddress = str;
            System.out.println("Adress whould be " + str);


            Endpoint.publish(str, this);


             System.out.println("file path whould be?");
            try {
                str = br.readLine();
            } catch (Exception e) {
            }
            ;
            file = str;


             System.out.println("Enter full address of balancer, for example 'http://localhost:9090/BalancerService/service'");
            try {
                str = br.readLine();
            } catch (Exception e) {
            }
            ;

            if (str.equalsIgnoreCase("")) {
                str = "http://localhost:9090/BalancerService/service";
            }



            this.connectBalancer(str);
            control();
            System.exit(0);


        }
        ;
    }

    public Record select(String key) {
        Log.mes("Block::select");
        Record r = new Record();
        r.name = "no row selected";
        r.phone = "";

        for (Record buf : records) {
            if (buf.name.equalsIgnoreCase(key)) {
                r = buf;
                break;
            }
        }
        ;

        return r;

    }

    ;





    public  void publish(String str)  {
        myAddress = str;
         Endpoint.publish (str, this);
};
    public void insert(Record record) {
        Log.mes("Master"+myAddress+" insert "+record.name + " "+ record.phone);
        for (Record buf : records) {
            if (buf.name == record.name) {
                return;
            }
        }
        ;

        records.add(record);
    }

    ;

    public void delete(String key) {
        for (int i = 0; i < records.size(); i++) {
            if (records.get(i).name.equalsIgnoreCase(key)) {
                records.remove(i);
                return;
            }
        }
        ;
    }

    ;

    public void update(Record record) {
        for (int i = 0; i < records.size(); i++) {
            if (records.get(i).name == record.name) {
                records.get(i).phone = record.phone;
                return;
            }
        }
        ;
    }

    ;

    public void load(String filePath) {
        try {
            FileReader f = new FileReader(filePath);
            BufferedReader br = new BufferedReader(f);
            String s;
            records.clear();
            parameters.startHash = Long.parseLong(br.readLine());
            parameters.stopHash = Long.parseLong(br.readLine());
            long size = 0;
            size = Long.parseLong(br.readLine());
            for (long i = 0; i < size; i++) {
                Record r = new Record();
                r.name = br.readLine();
                r.phone = br.readLine();
                records.add(r);
            }


            f.close();
        } catch (Exception e) {
        }
        ;
    }

    ;

    public void store() {
        Log.mes("Start store " +file);
        try {
            FileWriter f = new FileWriter(file);
            f.write(Long.toString(parameters.startHash) + "\n");
            f.write(Long.toString(parameters.stopHash) + "\n");
            f.write(Long.toString(records.size()) + "\n");

            for (Record r : records) {
                f.write(r.name + "\n");
                f.write(r.phone + "\n");
            }
            f.close();
            records.clear();
        } catch (Exception e) {
        }
        ;
        Log.mes("Stop store");
    }

    private void control() {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        System.out.print("Enter a command. 'help' - if you wanna help\n");
        do {


            try {
                str = br.readLine();
            } catch (Exception e) {
            }
            ;



            if (str.equalsIgnoreCase("help")) {
                System.out.print("insert,select,delete,update\n");
            }

            if (str.equalsIgnoreCase("select")) {
                System.out.print("print name\n");
                try {
                    str = br.readLine();
                } catch (Exception e) {
                }
                ;

                Record r = select(str);
                printRecord(r);
            }

            if (str.equalsIgnoreCase("delete")) {
                System.out.print("print name\n");
                try {
                    str = br.readLine();
                } catch (Exception e) {
                }
                ;

                delete(str);

            }


            if (str.equalsIgnoreCase("insert")) {
                System.out.print("insert name\n");
                try {
                    str = br.readLine();
                } catch (Exception e) {
                }
                ;

                Record r = new Record();
                r.name = str;

                System.out.print("insert phone\n");
                try {
                    str = br.readLine();
                } catch (Exception e) {
                }
                ;

                r.phone = str;

                insert(r);
            }


            if (str.equalsIgnoreCase("exit")) {
                store();
            }

            System.out.print("Enter a command. 'help' - if you wanna help\n");

        } while (!str.equalsIgnoreCase("exit"));

    }

    ;

    static void printRecord(Record r) {
        System.out.print(r.name + " " + r.phone + "\n");
    }

    ;

    public long numberOfRecords()
    {
      return records.size();
    };

    public void connectBalancer(String address)
    {
       try {
       System.out.println("Connecting Balancer");
       balancer = (new bd.artefacts.BalancerService( new URL(address), new QName("http://balancer.bd/", "BalancerService")) ).getBalancerPort();
       balancer.registerMaster(myAddress);
        } catch (Exception e) {System.out.println("Fucking shit in the connect Balancer");};
    };


    public void givePartOfBase(String address, long hashStart, long hashStop)
    {

        ArrayList<Record> temprecords = new ArrayList<Record>();
        Log.mes("Master "+myAddress+" giving some base to "+address);
        try {
        bd.artefacts.Master otherMaster = (new bd.artefacts.MasterService(new URL(address),new QName("http://master.bd/", "MasterService"))).getMasterPort();
        for (Record r : records)
            {
             long h  =  Hash.getHash(r.name);
               Log.mes("Обрабатываю "+ r.name);
             if ((h>=hashStart) && (h<=hashStop))
                 {
                 bd.artefacts.Record rec = new bd.artefacts.Record();
                 rec.setName(r.name);
                 rec.setPhone(r.phone);
                 otherMaster.insert(rec);
                  Log.mes("   послал");
                 
             } else {
                 Log.mes("   оставил");
                temprecords.add(r);
             }
            }
        records = temprecords;
        } catch (Exception e) {System.out.println("Fucking shit in the connect with other master" + e.getMessage());};
    };

}
